/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package xdxn.editor.studio.geom;

/**
 * 二维向量类 double
 */
public class Vector2D {

    public double x;
    public double y;

    public Vector2D() {
        this.x = 0;
        this.y = 0;
    }

    public Vector2D( double x , double y ) {
        this.x = x;
        this.y = y;
    }

    public Vector2D( Vector2D vec2 ) {
        this.x = vec2.x;
        this.y = vec2.y;
    }

    public double distance( Vector2D v ) {
        return Math.sqrt(distance_sq(v));
    }

    public static double distance( double x1 , double y1 , double x2 , double y2 ) {
        return Math.sqrt(distance_sq(x1 , y1 , x2 , y2));
    }

    public double distance_sq( Vector2D v ) {
        double disX = v.x - this.x;
        double disY = v.y - this.y;
        return disX * disX + disY * disY;
    }

    public static double distance_sq( double x1 , double y1 , double x2 , double y2 ) {
        double disX = x2 - x1;
        double disY = y2 - y1;
        return disX * disX + disY * disY;
    }

    public static double distance_sq( Vector2D v1 , Vector2D v2 ) {
        return v1.distance(v2);
    }

    public void add( Vector2D v ) {
        this.x += v.x;
        this.y += v.y;
    }

    public Vector2D add_return_new( Vector2D v ) {
        this.x += v.x;
        this.y += v.y;
        return new Vector2D(this.x , this.y);
    }

    public Vector2D add_return( Vector2D v ) {
        this.x += v.x;
        this.y += v.y;
        return this;
    }

    public Vector2D sub_return_new( Vector2D v ) {
        this.x -= v.x;
        this.y -= v.y;
        return new Vector2D(this.x , this.y);
    }

    public Vector2D sub_return( Vector2D v ) {
        this.x -= v.x;
        this.y -= v.y;
        return new Vector2D(this.x , this.y);
    }

    public void sub( Vector2D v ) {
        this.x -= v.x;
        this.y -= v.y;
    }

    public double dot( Vector2D v ) {
        return this.x * v.x + this.y * v.y;
    }

    public double cross( Vector2D v ) {
        return x * v.y - y * v.x;
    }

    public double mag() {
        return x * x + y * y;
    }

    public Vector2D div_return( double n ) {
        this.x /= n;
        this.y /= n;
        return this;
    }

    public Vector2D div_return_new( double n ) {
        this.x /= n;
        this.y /= n;
        return new Vector2D(this.x , this.y);
    }

    public void div( double n ) {
        this.x /= n;
        this.y /= n;
    }

    public void normalize() {
        double m = Math.sqrt(mag());
        if ( m != 0 ) {
            div(m);
        }
    }

    public double normalize_return() {
        double m = Math.sqrt(mag());
        if ( m != 0 ) {
            div(m);
        }
        return m;
    }

    public void zero() {
        this.x = 0;
        this.y = 0;
    }

    public Vector2D reverse_return() {
        this.x = -this.x;
        this.y = -this.y;
        return new Vector2D(this.x , this.y);
    }

    public Vector2D reverse_return_new() {
        this.x = -this.x;
        this.y = -this.y;
        return new Vector2D(this.x , this.y);
    }

    public void reverse() {
        this.x = -this.x;
        this.y = -this.y;
    }

    public static double angle( Vector2D v1 , Vector2D v2 ) {
        if ( v1.mag() != 1.0f ) {
            v1.normalize();
        }
        if ( v2.mag() != 1.0f ) {
            v2.normalize();
        }
        return Math.acos(v1.dot(v2));
    }

    public void rotateCCW90() {
        double t = this.x;
        this.x = -this.y;
        this.y = t;
    }

    public void rotateCW90() {
        double t = this.x;
        this.x = this.y;
        this.y = -t;
    }

    public void setLength( double length ) {
        normalize();
        this.x *= length;
        this.y *= length;
    }
}
